package com.yangfan.thread.thread_wangwenjun04;

import java.util.*;

/**
 * @description: 数据采集案例  模仿线程池 多线程一起做  任务
 * @author: yangfan
 * @date: Created in 2020/1/27 0027 17:18
 * @modified By:
 *
 * 比较牛逼的案例
 *
 */
public class CaptureService {

    /**
     * 链表结构的锁，每次一个线程执行任务 都会调用 CONTROL.addLast(new Control()) 在末尾加一个控制
     *      任务完成后 在调用  CONTROL.removeFirst(); 删除第一个位置的控制
     */
    private static final LinkedList<Control> CONTROL = new LinkedList<>();

    private static final int MAX_THREAD_PARALLEL_NUM = 2; //自定义可同时 并行的线程数量


    public static void main(String[] args) {

        //用来保存线程的集合
        List<Thread> worker = new ArrayList<>();

        //创建多个线程 并把他们加入到 集合中
        Arrays.asList("M1", "M2", "M3", "M4", "M5", "M6", "M7", "M8", "M9", "M10")
                .stream().map(CaptureService::createCaptureThread)
                .forEach((t) -> {
                    t.start();
                    worker.add(t);
                });

        //把启动线程 join 住让其主线程等待 子线程全部 执行完毕 在 做其他 操作
        worker.stream().forEach((t) ->{
            try {
                t.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Optional.of("最后啥都执行完了。。主线程即将结束").ifPresent(System.out::println);

    }


    private static Thread createCaptureThread(String name) {

        return new Thread(() -> {

            synchronized (CONTROL){

                while (MAX_THREAD_PARALLEL_NUM <= CONTROL.size() ){

                    //如果超过最大数量则等待
                    try {
                        CONTROL.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }

                /**
                 * 这一步不知道啥意思
                 * 猜测：新增加一个控制，放在末尾
                 */
                CONTROL.addLast(new Control());

            }

            //如果没有超过最大数量则进行工作

            Optional.of(Thread.currentThread().getName()+"!!!!!!!!!! 线程开始执行任务！ !!!!!!!!!!").ifPresent(System.out::println);
            try {
                Thread.sleep(10_000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


            synchronized (CONTROL){
                Optional.of(Thread.currentThread().getName()+"============ 线程任务执行完毕 ============").ifPresent(System.err::println);
                //告诉其他线程我已经做完了
                CONTROL.removeFirst();
                CONTROL.notifyAll();
            }


        }, name);
    }

    /**
     * 用于控制 无实际用途
     */
    private static class Control{

    }

}
